package com.hanxiaozhang.system.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.hanxiaozhang.annotation.EnableGlobalException;
import com.hanxiaozhang.result.Result;
import com.hanxiaozhang.system.dto.MenuDTO;
import com.hanxiaozhang.system.dto.TreeDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hanxiaozhang.system.entity.MenuEntity;
import com.hanxiaozhang.system.service.MenuService;


/**
 * 菜单表
 *
 * @author hanxiaozhang
 * @email hanxiaozhang2018@sina.com
 * @date 2021-03-30
 */
@Slf4j
@Controller
@RequestMapping("/menu")
@EnableGlobalException
public class MenuController {

    @Autowired
    private MenuService menuService;

    /**
     * 查询列表
     *
     * @param params
     * @return
     */
    @ResponseBody
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('system:menu:list')")
    public Result list(@RequestParam Map<String, Object> params) {

        List<MenuDTO> menuList = menuService.list(params);
        handleChildrenNode(menuList);
        return Result.success(menuList);
    }

    /**
     * 处理孩子节点
     *
     * @param menuList
     */
    private void handleChildrenNode(List<MenuDTO> menuList) {
        if (menuList.isEmpty()) {
            return;
        }
        List<MenuDTO> allMenuList = menuService.list(new HashMap<>(4));
        listMenuRecursion(menuList, "无", allMenuList);
    }

    /**
     * 递归查询
     *
     * @param menuList
     * @param parentName
     * @param allMenuList
     */
    private void listMenuRecursion(List<MenuDTO> menuList, String parentName, List<MenuDTO> allMenuList) {
        if (!menuList.isEmpty()) {
            menuList.forEach(x -> {
                Long menuId = x.getMenuId();
                List<MenuDTO> childrenList = allMenuList.stream().filter(y -> menuId.equals(y.getParentId())).collect(Collectors.toList());
                x.setParentName(parentName);
                x.setChildren(childrenList);
                listMenuRecursion(childrenList, x.getMenuName(), allMenuList);
            });
        }
        return;
    }


    /**
     * 保存
     *
     * @param menu
     * @return
     */
    @ResponseBody
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('system:menu:save')")
    public Result<Void> save(MenuDTO menu) {

        menuService.save(menu);
        return Result.success();
    }


    /**
     * 修改
     *
     * @param menu
     * @return
     */
    @ResponseBody
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('system:menu:update')")
    public Result<Void> update(MenuDTO menu) {

        menuService.update(menu);
        return Result.success();
    }


    /**
     * 删除
     *
     * @param menuId
     * @param parentId
     * @return
     */
    @PostMapping("/remove")
    @ResponseBody
    @PreAuthorize("hasAuthority('system:menu:remove')")
    public Result<Void> remove(Long menuId, Long parentId) {


        return menuService.remove(menuId, parentId);
    }


    /**
     * 批量删除
     *
     * @param menuIds
     * @param parentIds
     * @return
     */
    @PostMapping("/batchRemove")
    @ResponseBody
    @PreAuthorize("hasAuthority('system:menu:batchRemove')")
    public Result<Void> batchRemove(Long[] menuIds, Long[] parentIds) {

        return menuService.batchRemove(menuIds, parentIds);
    }

    /**
     * 菜单树
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/tree")
    public Result tree() {

        List<MenuDTO> allMenuList = menuService.list(new HashMap<String, Object>(4));

        List<TreeDTO> routerList = new ArrayList<>();
        for (MenuEntity menu : allMenuList) {
            if (menu.getParentId() == 0) {
                routerList.add(menuToTree(menu));
            }
        }
        listTreeRecursion(routerList, allMenuList);
        return Result.success(routerList);
    }

    /**
     * 递归查询
     *
     * @param treeList
     * @param allMenuList
     */
    private void listTreeRecursion(List<TreeDTO> treeList, List<MenuDTO> allMenuList) {
        if (!treeList.isEmpty()) {
            treeList.forEach(x -> {
                Long menuId = x.getKey();
                List<MenuEntity> childrenMenuList = allMenuList.stream()
                        .filter(y -> menuId.equals(y.getParentId())).collect(Collectors.toList());
                List<TreeDTO> childrenRouterList = new ArrayList<>();
                if (!childrenMenuList.isEmpty()) {
                    for (MenuEntity childrenMenu : childrenMenuList) {
                        childrenRouterList.add(menuToTree(childrenMenu));
                    }
                }
                x.setChildren(childrenRouterList);
                listTreeRecursion(childrenRouterList, allMenuList);
            });
        }
        return;
    }


    /**
     * 菜单转树
     *
     * @param menu
     * @return
     */
    private TreeDTO menuToTree(MenuEntity menu) {
        return TreeDTO.builder()
                .key(menu.getMenuId())
                .value(menu.getMenuId())
                .parentId(menu.getParentId())
                .title(menu.getMenuName())
                .disabled(menu.getStatus() == 0 ? true : false)
                .build();
    }


}
